package com.knowledge.review.designPatterns.structuralpattern.proxypattern;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

// 火车站接口，有卖票功能
public interface TrainStation1 {
    void sellTickets();
}

// 广州火车站卖票
class GuangzhouTrainStation1 implements TrainStation1 {
    @Override
    public void sellTickets() {
        System.out.println("广州火车站卖票啦");
    }
}

// 深圳火车站卖票
class ShenzhenTrainStation implements TrainStation1 {
    @Override
    public void sellTickets() {
        System.out.println("深圳火车站卖票啦");
    }
}

// 代售点卖票（代理类）
//class ProxyPoint1 implements InvocationHandler {
//    private TrainStation1 trainStation;
//
//    public TrainStation1 getProxyObject(TrainStation1 trainStation) {
//        this.trainStation = trainStation;
//        Class<? extends TrainStation1> clazz = trainStation.getClass();
//        return (TrainStation1) Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
//    }
//
//    @Override
//    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//        System.out.println("代售火车票收取5%手续费");
//        return method.invoke(this.trainStation, args);
//    }
//}

/**
 * 使用CGLIB动态代理
 */

// 代售点卖票（代理类）
class ProxyPoint1 implements MethodInterceptor {
    public TrainStation1 getProxyObject(Class<? extends TrainStation1> trainStation) {
        //创建Enhancer对象，类似于JDK动态代理的Proxy类，下一步就是设置几个参数
        Enhancer enhancer = new Enhancer();
        //设置父类的字节码对象
        enhancer.setSuperclass(trainStation);
        //设置回调函数
        enhancer.setCallback(this);
        //创建代理对象并返回
        return (TrainStation1) enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("代售火车票收取5%手续费");
        return methodProxy.invokeSuper(o, objects);
    }
}

class Test1 {
    /*
     *  动态代理
     */
//    public static void main(String[] args) {
//        ProxyPoint1 proxy = new ProxyPoint1();
//        TrainStation1 guangzhouTrainStation = proxy.getProxyObject(new GuangzhouTrainStation1());
//        // 代售火车票收取5%手续费
//        // 广州火车站卖票啦
//        guangzhouTrainStation.sellTickets();
//        TrainStation1 shenzhenTrainStation = proxy.getProxyObject(new ShenzhenTrainStation());
//        // 代售火车票收取5%手续费
//        // 深圳火车站卖票啦
//        shenzhenTrainStation.sellTickets();
//    }
    // 测试

    /*
     * CGLIB动态代理
     */
    public static void main(String[] args) {
        ProxyPoint1 proxy = new ProxyPoint1();
        TrainStation1 guangzhouTrainStation = proxy.getProxyObject(GuangzhouTrainStation1.class);
        // 代售火车票收取5%手续费
        // 广州火车站卖票啦
        guangzhouTrainStation.sellTickets();
        TrainStation1 shenzhenTrainStation = proxy.getProxyObject(ShenzhenTrainStation.class);
        // 代售火车票收取5%手续费
        // 深圳火车站卖票啦
        shenzhenTrainStation.sellTickets();
    }
}